﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Assertions.Must;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using static UnityEditor.Graphs.Styles;

namespace ttbit.form.unity
{
    class DrawLayer
    {
        public DrawLayer(IRenderTarget target, UnityEngine.Camera camera, UnityEngine.Transform tran)
        {
            this.target = target;
            this.camera = camera;
            this.tran = tran;
        }
        public IRenderTarget target;
        public UnityEngine.Camera camera;
        UnityEngine.Transform tran;
        public uint ID
        {
            get
            {
                return target.ID;
            }
        }

        public void Clear()
        {
            batchid = 0;
            foreach (var b in batches)
            {
                b.Clear();
            }
            if (camera.targetTexture != null)
            {
                camera.enabled = false;
            }


        }
        public void Begin(IRenderTarget target)
        {
            //规范摄像机
           
            camera.enabled = true;
            camera.backgroundColor = new UnityEngine.Color(target.ClearColor.R, target.ClearColor.G, target.ClearColor.B, target.ClearColor.A);
            camera.clearFlags = CameraClearFlags.SolidColor;
            camera.orthographic = true;

            camera.allowMSAA = false;
            camera.allowHDR = false;
            camera.orthographicSize =( target.height / 2.0f / target.Scale);
           
            camera.nearClipPlane = 0.1f;
            camera.farClipPlane = 1000;
            //if (target == Env.Graphic.MainScreen)
            if(camera.targetTexture==null)//此处要考虑玩意主Camera就是个RT的情况
            {
                camera.transform.position = new Vector3(target.LookAt.X, target.LookAt.Y, 10);
                camera.transform.LookAt(new Vector3(target.LookAt.X, target.LookAt.Y, 0), Vector3.down);
            }
            else
            {
                camera.transform.position = new Vector3(target.LookAt.X, target.LookAt.Y, -10);
                camera.transform.LookAt(new Vector3(target.LookAt.X, target.LookAt.Y, 0), Vector3.up);
            }


        }
        int batchid;
        List<Batch> batches = new List<Batch>();
        public void DrawRect(ITexture tex, Effect effect, Rect rect, Rect uv, UnityEngine.Color32 color)
        {

            while (batchid < batches.Count)
            {
                var last = batches[batchid];
                if (last.CanDraw(tex, effect, MeshTopology.Quads))
                {
                    last.DrawRect(rect, uv, color);
                    return;
                }
                else
                {
                    last.End();
                    batchid++;
                }
            }

            Batch batch = new Batch(tex, effect, MeshTopology.Quads, this.tran, batches.Count);
            batches.Add(batch);
            batch.DrawRect(rect, uv, color);
            batchid = batches.Count - 1;
        }
        public void DrawRectFree(ITexture tex, Effect effect, DrawPoint point0, DrawPoint point1, DrawPoint point2, DrawPoint point3)
        {
            while (batchid < batches.Count)
            {
                var last = batches[batchid];
                if (last.CanDraw(tex, effect, MeshTopology.Quads))
                {
                    last.DrawRectFree(point0, point1, point2, point3);
                    return;
                }
                else
                {
                    last.End();
                    batchid++;
                }
            }

            Batch batch = new Batch(tex, effect, MeshTopology.Quads, this.tran, batches.Count);
            batches.Add(batch);
            batch.DrawRectFree(point0, point1, point2, point3);
            batchid = batches.Count - 1;
        }
        public void DrawTris(ITexture tex, Effect effect, DrawPoint[] tris, int tricount)
        {
            while (batchid < batches.Count)
            {
                var last = batches[batchid];
                if (last.CanDraw(tex, effect, MeshTopology.Triangles))
                {
                    last.DrawTris(tris, tricount);
                    return;
                }
                else
                {
                    last.End();
                    batchid++;
                }
            }

            Batch batch = new Batch(tex, effect, MeshTopology.Triangles, this.tran, batches.Count);
            batches.Add(batch);
            batch.DrawTris(tris, tricount);
            batchid = batches.Count - 1;
        }
        public void DrawLines(ITexture tex, Effect effect, DrawPoint[] lines, int linecount)
        {
            while (batchid < batches.Count)
            {
                var last = batches[batchid];
                if (last.CanDraw(tex, effect, MeshTopology.Lines))
                {
                    last.DrawLines(lines, linecount);
                    return;
                }
                else
                {
                    last.End();
                    batchid++;
                }
            }

            Batch batch = new Batch(tex, effect, MeshTopology.Lines, this.tran, batches.Count);
            batches.Add(batch);
            batch.DrawLines(lines, linecount);
            batchid = batches.Count - 1;
        }
        public void DrawPoints(ITexture tex, Effect effect, DrawPoint[] points, int pointcount)
        {
            while (batchid < batches.Count)
            {
                var last = batches[batchid];
                if (last.CanDraw(tex, effect, MeshTopology.Points))
                {
                    last.DrawPoints(points, pointcount);
                    return;
                }
                else
                {
                    last.End();
                    batchid++;
                }
            }

            Batch batch = new Batch(tex, effect, MeshTopology.Points, this.tran, batches.Count);
            batches.Add(batch);
            batch.DrawPoints(points, pointcount);
            batchid = batches.Count - 1;
        }
        public void End()
        {
            if (batches.Count > 0)
            {
                batches[batches.Count - 1].End();
            }
        }
    }
}
